package com.wxl.asmgradleplugin.myplugin

import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.commons.AdviceAdapter

class LogMethodVisitor(
    private val className: String?,
    api: Int, mv: MethodVisitor?, access: Int, name: String?, desc: String?
) : AdviceAdapter(api, mv, access, name, desc) {

    private val addClass = "com/wxl/asmgradleplugin/demo/asm/LogUtil"

    override fun onMethodEnter() {
        super.onMethodEnter()
        println("====222 onMethodEnter: $name")
        if (name == "onCreate" && methodDesc == "(Landroid/os/Bundle;)V") {
            mv.visitLdcInsn("=== ASM")
            mv.visitLdcInsn("=== onCreate")
            mv.visitMethodInsn(
                INVOKESTATIC,
                "android/util/Log",
                "i",
                "(Ljava/lang/String;Ljava/lang/String;)I",
                false
            )
            mv.visitInsn(POP)
        } else if ("test" == name) {
            // 在方法开始处插入LogUtil.refreshTime()
            mv.visitLdcInsn(className)
            mv.visitLdcInsn(name)
            mv.visitMethodInsn(
                INVOKESTATIC,
                addClass,
                "refreshTime",
                "(Ljava/lang/String;Ljava/lang/String;)V",
                false
            )
        }
    }


    override fun onMethodExit(opcode: Int) {
        super.onMethodExit(opcode)
        println("====222 onMethodExit: $name")
        if ("test" == name) {
            // 在方法返回之前插入LogUtil.calFuncTime(packageName, methodName)
            //IRETURN（Opcodes.IRETURN）: 返回整数。
            //LRETURN（Opcodes.LRETURN）: 返回长整数。
            //FRETURN（Opcodes.FRETURN）: 返回浮点数。
            //DRETURN（Opcodes.DRETURN）: 返回双精度浮点数。
            //ARETURN（Opcodes.ARETURN）: 返回对象引用。
            //RETURN（Opcodes.RETURN）: 用于返回void。
            //这部分检查当前指令是否是ATHROW，即抛出异常指令。
            if (opcode >= IRETURN && opcode <= RETURN || opcode == ATHROW) {
                mv.visitLdcInsn(className)
                mv.visitLdcInsn(name)
                mv.visitMethodInsn(
                    INVOKESTATIC,
                    addClass,
                    "calFuncTime",
                    "(Ljava/lang/String;Ljava/lang/String;)V",
                    false
                )
            }
        }
    }

}